var tgd = tgd || {};
tgd.Tools = tgd.Tools || {};
tgd.Tools.ContactDiff = tgd.Tools.ContactDiff || {};
tgd.Tools.ContactDiff.GUI = tgd.Tools.ContactDiff.GUI || {};

/*
 * represents a unique contact
 */
 
tgd.Tools.ContactDiff.GUI = function (model) {
    var _m = model;
    var _v = [];  //array of contact views
    var _vuc = [];  //array of contact views for a user's contacts  TODO: cache these
    var _numUniques = 0;
    var _numIdenticals = 0;
    var _numCommons = 0;
    var _loaded = false;

    this.__defineGetter__("NumUniques", function() { return _numUniques; });
    this.__defineGetter__("NumIdenticals", function() { return _numIdenticals; });
    this.__defineGetter__("NumCommons", function() { return _numCommons; });
    this.__defineGetter__("isLoaded", function() { return _loaded; });

    this.setPanel = function (pan) {
        this.Panels.Main.hide();
        this.Panels.User.hide();
        this.Panels.Contacts.hide();

        pan.show();
    }

    /*
     * PRIVATE
     * TODO: not done here, but make "OriginalContacts" have friendly names like "Properties" on contact object.
     */
    this._recursiveUserContact = function (props, ele, path) {
	    for (var prop in props) {
		    if (typeof props[prop] === "string" || typeof props[prop] === "number") {
			    var pDiv = document.createElement("div");
			    pDiv.className = "listRow";  //todo: remove once templates are used
			    pDiv.textContent = "[" + path + (path === "" ? "" : ".") + prop + "]   " + props[prop];
			    ele.appendChild(pDiv);
		    } else { //object or array
			    this._recursiveUserContact(props[prop], ele, path + (path === "" ? "" : ".") + prop)
		    }
	    }
    }

    /*
     * PRIVATE
     * TODO: templatize, cache the views per user
     */
    this._loadContactsForUser = function (u) {

        var contactTemplate = this.Panels.Templates.getElementsByClassName("contact")[0];
        var repeater = this.Repeaters.UserContacts;
	    repeater.innerHTML = "";
	    _vuc = [];

        for (var i = 0; i < mod.Contacts.length; ++i) {
            var currentContact = mod.Contacts[i];
            if (currentContact.Users.some( function (element, index, array) { return element.Name === u.Name; } )) {
                var div = contactTemplate.cloneNode(true);
                var newView = new tgd.Tools.ContactDiff.ContactView(currentContact, div, u);
                newView.toggle(false);
                _vuc.push(newView);
                repeater.appendChild(div);
                
                //var div = document.createElement("h2");
		        //div.textContent = currentContact.Name;
		        //repeater.appendChild(div);
		        //this._recursiveUserContact(u.OriginalContacts[i], repeater, "");
            }
        }
    }

    if (tgd.Tools.ContactDiff.GUI._initialized === undefined) {

        tgd.Tools.ContactDiff.GUI.prototype.Panels = {
            Main : document.getElementById("panMain"),
            User : document.getElementById("panUser"),
            Contacts : document.getElementById("panContacts"),
            Templates : document.getElementById("templates"),
            Loading : document.getElementById("panLoading"),
            UserList : document.getElementById("panUserList"),
            ContactsMenu : document.getElementById("panContactMenu"),
            UserContactsMenu : document.getElementById("panUserContactsMenu")
        }

        tgd.Tools.ContactDiff.GUI.prototype.Labels = {
            User : document.getElementById("lblUser")
        }

        tgd.Tools.ContactDiff.GUI.prototype.Repeaters = {
            UserContacts : document.getElementById("repUserContacts"),
            Contacts : document.getElementById("repContacts")
        }

        tgd.Tools.ContactDiff.GUI.prototype.Enums = {
            Differences : 0,
            Matches : 1,
            All : 2
        }

        tgd.Tools.ContactDiff.GUI._initialized = true;
    }


    /*
     * Display the users from the model.
     * Wire up >> click to display "user page".
     */
    this.loadUserList = function () {
        var self = this;
	    var listRow = this.Panels.Templates.getElementsByClassName("listRow")[0];
	    var users = mod.Users;

	    for (var i = 0; i < users.length; ++i) {
		    var div = listRow.cloneNode(true);
		    var btn = div.getElementsByClassName("rowButton")[0];
		    var lbl = div.getElementsByClassName("rowText")[0];

		    lbl.textContent = users[i].Name;
		    btn.user = users[i];

		    btn.onclick = function(event) {
		        currentUser = event.target.user;
			    self.Labels.User.textContent = currentUser.Name;
			    self._loadContactsForUser(currentUser);
			    self.setPanel(self.Panels.User);
		    }

		    this.Panels.UserList.appendChild(div);
	    }
    }

    /*
     * Display all of the contacts.
     * TODO: define what the "default" view is, so the model can assume it.
     */
    this.loadContacts = function() {
        if (_loaded) {
            return;
        }

        this.Repeaters.Contacts.innerHTML = "";
        var contactTemplate = this.Panels.Templates.getElementsByClassName("contact")[0];

        for (var i = 0; i < mod.Contacts.length; ++i) {
            var div = contactTemplate.cloneNode(true);
            var newView = new tgd.Tools.ContactDiff.ContactView(mod.Contacts[i], div)
            
            _v.push(newView);

            /*
             * Setup contact views for "default" display.
             */
            _v[i].showAll();
            _v[i].toggle(false);
            if (_v[i].Contact.IsIdentical) {
                _v[i].hide();
                ++_numIdenticals;
            } else if (_v[i].Contact.IsUnique) {
                _v[i].hide();
                ++_numUniques
            } else {
                _v[i].show();
                ++_numCommons;
            }

            this.Repeaters.Contacts.appendChild(div);
        }

        _loaded = true;
    }

    /*
     * Collapse all contacts
     */
    this.collapseContacts = function() {
        for (var i = 0; i < _v.length; ++i) {
            _v[i].toggle(false);
        }
    }

    /*
     * Expand all contacts
     */
    this.expandContacts = function() {
        for (var i = 0; i < _v.length; ++i) {
            _v[i].toggle(true);
        }
    }

    /*
     * Collapse all of the user's contacts
     */
    this.collapseUserContacts = function() {
        for (var i = 0; i < _vuc.length; ++i) {
            _vuc[i].toggle(false);
        }
    }

    /*
     * Expand all of the user's contacts
     */
    this.expandUserContacts = function() {
        for (var i = 0; i < _vuc.length; ++i) {
            _vuc[i].toggle(true);
        }
    }

    /*
     * Show all properties for all contacts.
     * The collapsed state of the contact is not changed.
     */
    this.showAll = function() {
        for (var i = 0; i < _v.length; ++i) {
            _v[i].showAll();
        }
    }

    /*
     * Show all properties w/ differences for all contacts.
     * The collapsed state of the contact is not changed.
     */
    this.showDifferences = function() {
        for (var i = 0; i < _v.length; ++i) {
            _v[i].showDifferences();
        }
    }

    /*
     * Show all matching properties for all contacts.
     * The collapsed state of the contact is not changed.
     */
    this.showMatches = function() {
        for (var i = 0; i < _v.length; ++i) {
            _v[i].showMatches();
        }
    }

    var _idens = false;
    var _uniqs = false;
    var _comms = true;

    /*
     * Show/hide the contacts which all users have and all properties are identical.
     * show - boolean - optional - If provided determines if the contacts are shown (TRUE) or hidden (FALSE).
     */
    this.toggleIdenticals = function(show) {
        if (show !== undefined) {
            _idens = !show;
        }

        for (var i = 0; i < _v.length; ++i) {
            if (_v[i].Contact.IsIdentical) {
                if (_idens) {
                    _v[i].hide();
                } else {
                    _v[i].show();
                }
            }
        }

        _idens = !_idens;
    }

    /*
     * Show/hide the contacts which only one user has.
     * show - boolean - optional - If provided determines if the contacts are shown (TRUE) or hidden (FALSE).
     */
    this.toggleUniques = function(show) {
        if (show !== undefined) {
            _uniqs = !show;
        }

        for (var i = 0; i < _v.length; ++i) {
            if (_v[i].Contact.IsUnique) {
                if (_uniqs) {
                    _v[i].hide();
                } else {
                    _v[i].show();
                }
            }
        }

        _uniqs = !_uniqs;
    }

    /*
     * Show/hide the contacts that are not unique or identical.
     * show - boolean - optional - If provided determines if the contacts are shown (TRUE) or hidden (FALSE).
     */
    this.toggleCommons = function(show) {
        if (show !== undefined) {
            _comms = !show;
        }

        for (var i = 0; i < _v.length; ++i) {
            if (!(_v[i].Contact.IsIdentical || _v[i].Contact.IsUnique)) {
                if (_comms) {
                    _v[i].hide();
                } else {
                    _v[i].show();
                }
            }
        }

        _comms = !_comms;
    }
}

